import { Component, OnInit, Input, Output, EventEmitter, OnChanges, OnDestroy, Renderer2, SimpleChanges, TemplateRef, ContentChild } from '@angular/core';
import { SafeStyle, DomSanitizer } from '@angular/platform-browser';
import { DocumentWrapper, WindowWrapper } from '../shared/services';
import { dialogFadeAnimation } from '../shared/animation/index';

@Component({
  selector: 'el-dialog',
  templateUrl: './dialog.component.html',
  animations: [dialogFadeAnimation]
})
export class DialogComponent implements OnInit {
  @Input() visible: boolean = false;
  @Input() title: string = '';
  @Input() width: string = '';
  @Input() center: boolean = false;
  @Input() top: string = '15%';
  @Input('close-on-click-modal') closeOnClickModal: boolean = true;
  @Input('close-on-press-escape') closeOnPressEscape: boolean = true;
  @Input('lock-scroll') lockScroll: boolean = true;
  @Input('custom-class') customClass: string = '';
  @Input('show-close') showClose: boolean = true;
  @Input('before-close') beforeClose: any = (function (d: any) { return d(); });
  @Input() dialogZindex: number = 2000;
  @Input() modalZindex: number = 1999;
  
  @Output('close') visibleChange: EventEmitter<boolean> = new EventEmitter();
  private sanitizer: any;
  private renderer: any;
  private window: any;
  private document: any;
  @ContentChild('title') titleTmp!: TemplateRef<any>;
  @ContentChild('footer') footerTmp!: TemplateRef<any>;
  @Input() cacheOverflow: string = '';
  @Input() cacheModalElement!: any;
  @Input() globalListenFunc!: Function;

  constructor(sanitizer: DomSanitizer, renderer: Renderer2, window: WindowWrapper, document: DocumentWrapper) {
    this.sanitizer = sanitizer;
    this.renderer = renderer;
    this.window = window;
    this.document = document;
  }

  ngOnInit(): void {
    var _this = this;
    // save old overflow
    if (this.lockScroll) {
      this.cacheOverflow = this.window.getComputedStyle(this.document.body).overflow;
    }
    this.cacheModalElement = this.renderer.createElement('div');
    this.renderer.setAttribute(this.cacheModalElement, 'class', 'v-modal');
    this.renderer.setStyle(this.cacheModalElement, 'z-index', this.modalZindex);
    this.renderer.setStyle(this.cacheModalElement, 'display', this.visible ? 'block' : 'none');
    this.document.body.appendChild(this.cacheModalElement);
    // listen esc
    if (this.closeOnPressEscape) {
      this.globalListenFunc = this.renderer.listen('document', 'keydown', function (event:any) {
        _this.visible && event.keyCode === 27 && _this.closeHandler();
      });
    }
  }


  makeDialogStyles(): SafeStyle {
    var /** @type {?} */ width = this.width ? "width: " + this.width + ";" : '';
    var /** @type {?} */ styles = "top: " + this.top + ";" + width;
    return this.sanitizer.bypassSecurityTrustStyle(styles);
  };


  closeHandler(): void {
    var _this = this;
    this.beforeClose(function () {
      _this.visible = false;
      _this.visibleChange.emit(_this.visible);
      _this.updateWithVisibleChange();
    });
  };


  wrapperClickHandle(): void {
    if (this.closeOnClickModal) {
      this.closeHandler();
    }
  };


  updateWithVisibleChange(): void {
    if (this.cacheModalElement) {
      // this.cacheModalElement.innerHTML = this.makeModalTmp(this.visible)
      this.renderer.setStyle(this.cacheModalElement, 'display', this.visible ? 'block' : 'none');
    }
    // lock body scroll
    if (this.lockScroll) {
      var /** @type {?} */ nextValue = this.visible ? 'hidden' : this.cacheOverflow;
      this.renderer.setStyle(this.document.body, 'overflow', nextValue);
    }
  };


  ngOnChanges(changes: SimpleChanges): void {
    if (!changes || !changes.visible)
      return;
    this.visible = changes.visible.currentValue;
    this.updateWithVisibleChange();
  };


  ngOnDestroy(): void {
    this.globalListenFunc && this.globalListenFunc();
    this.cacheModalElement.parentElement.removeChild(this.cacheModalElement);
    this.renderer.setStyle(this.document.body, 'overflow', this.cacheOverflow);
  };
}
